/*
 * @Author: xiaosihan
 * @Date: 2021-05-02 22:16:33
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2021-07-29 01:26:46
 */

import _ from "lodash";
import React from "react";
import * as THREE from "three";
import { WebGLRenderTarget } from "three";
import LineSegments from "../LineSegments/LineSegments";
import Mesh from "../Mesh/Mesh";
import Object3D from "../Object3D/Object3D";
import Object3DComponent, { Object3DComponentProps } from "../Object3D/Object3DComponent";
import Transition from "../xrt_util/Transition";
import TransitionColor from "../xrt_util/TransitionColor";

export interface DirectionalLightProps extends Object3DComponentProps {
    color?: string, // 光照颜色
    intensity?: number, // 光照强度
    shadowResolution?: number, // 阴影分辨率
    shadowSize?: number, // 阴影的尺寸
    castShadow?: boolean, // 创建阴影
}

interface State {
}

export default class DirectionalLight extends Object3DComponent<DirectionalLightProps, State> {
    constructor(props: DirectionalLightProps) {
        super(props);

        this.object3d.add(this.directionalLight);

        this.directionalLight.target.position.z = 1;// 照射目标
        this.directionalLight.target.matrixAutoUpdate = false;
        this.directionalLight.target.updateMatrix();
        this.directionalLight.add(this.directionalLight.target);
    }

    // 平行光对象
    directionalLight = new THREE.DirectionalLight() as unknown as THREE.DirectionalLight & Object3D;

    // 颜色缓动对象
    Tcolor = new TransitionColor(this.props.color || "#fff");

    // 灯光参数
    lightParams = new Transition();

    // 正方形网格模型
    planGeometry = new THREE.PlaneBufferGeometry(1, 1, 1, 1);

    componentBeforeRender() {

        let keepRun = this.setLightParam();

        return keepRun;
    }

    // 设置光照的参数
    setLightParam() {
        let keepRun = false;

        // 光照颜色
        if (!this.Tcolor.isDone()) {
            const { r, g, b } = this.Tcolor.getJson();
            this.directionalLight.color.setRGB(r, g, b);
            keepRun = true;
        }

        if (!this.lightParams.isDone()) {
            const { intensity, shadowSize } = this.lightParams.getJson();

            this.directionalLight.intensity = intensity;

            let sideLength = shadowSize / 2;
            this.directionalLight.shadow.camera.left = - sideLength;
            this.directionalLight.shadow.camera.right = sideLength;
            this.directionalLight.shadow.camera.top = sideLength;
            this.directionalLight.shadow.camera.bottom = - sideLength;
            this.directionalLight.shadow.camera.updateProjectionMatrix();
            keepRun = true;
        }

        return keepRun;
    }

    // 设置光照的过渡参数
    setLightTransParam() {

        const {
            bezier,
            duration = 500,
            color = "#fff", // 光照颜色
            intensity = 1, // 光照强度
            shadowResolution = 512, // 阴影分辨率
            shadowSize = 10, // 阴影的尺寸
            castShadow = false, // 创建阴影
        } = this.props;

        this.Tcolor.setBezier(bezier).setDuration(duration).set(color);

        this.lightParams.setBezier(bezier).setDuration(duration).set({ intensity, shadowSize });

        // 分辨率直接赋值 不能有缓动效果
        this.directionalLight.shadow.mapSize.set(shadowResolution, shadowResolution);

        if (this.directionalLight.shadow.map) {
            (this.directionalLight.shadow.map as WebGLRenderTarget).setSize(shadowResolution, shadowResolution);
        }

        // 是否创建阴影
        this.directionalLight.castShadow = castShadow;
    }

    componentDidMount() {
        // 减少双面物体的自阴影
        this.directionalLight.shadow.normalBias = -0.05;
        this.setLightTransParam();
        this.setLightParam();
    }

    componentDidUpdate() {
        this.setLightTransParam();
    }

    render() {

        const { dev } = this.context;

        if (!dev) {
            return null;
        }

        let { color = "#fff", shadowSize = 10, intensity = 1 } = this.props;

        // 当sideLength长小于10的时候  虚线方框的最小边长为10,  不然就看不到 虚线方框了
        let l = _.clamp(shadowSize / 2, 5, shadowSize / 2);

        return (
            <>
                <LineSegments
                    position={{ x: 0, y: 0, z: 0 }}
                    points={[
                        [-l, l, 0], [l, l, 0],
                        [l, l, 0], [l, -l, 0],
                        [l, -l, 0], [-l, -l, 0],
                        [-l, -l, 0], [-l, l, 0],
                        [0, 0, 0], [0, 0, 10],
                    ]}
                    clipping={false}
                    dashSize={1}
                    gapSize={1}
                    dashSpeed={1}
                    color={[color]}
                />
                <Mesh
                    scale={{ x: l * 2, y: l * 2 }}
                    side={THREE.DoubleSide}
                    color={color}
                    geometry={this.planGeometry}
                    material="MeshBasicMaterial"
                    clipping={false} // 不使用裁剪
                    cursor="pointer"
                    wireframe={true}
                    title={
                        <div
                            style={{
                                position: "relative",
                                backgroundColor: "rgba(0, 0, 0, 0.8)",
                                borderRadius: 4,
                                padding: "4px 8px",
                                color: "#fff"
                            }}
                        >
                            <span>{"方向光"}<br /></span>
                            <span>{"<DirectionalLight/>"}<br /></span>
                        </div>
                    }
                />
            </>
        );
    }
}